package com.zzuli.yxy.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzuli.yxy.ListStringConverter;
import com.zzuli.yxy.entity.Role;
import com.zzuli.yxy.result.R;
import com.zzuli.yxy.mapper.RoleMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.zzuli.yxy.service.RoleService;

import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;

/**
 * @auther pony
 * @create 2023-03-28 15:34
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Autowired
    private RoleMapper roleMapper;
    /**
     * 获取全部状态正常的角色信息
     * @return
     */
    @Override
    public R getAllRole() {
        LambdaQueryWrapper<Role> qw = new LambdaQueryWrapper<>();
        qw.eq(Role::getStatus, 0);
        List<Role> roles = roleMapper.selectList(qw);
        return R.success().message("角色信息").data("role",roles);
    }

    /**
     * 获取角色管理分页列表信息
     * @param pageCurrent 当前页码
     * @param pageSize 每页条数
     * @param name 查询关键字
     * @return
     */
    @Override
    public R getPage(Integer pageCurrent, Integer pageSize, String name) {
        Page<Role> pageInfo = new Page<>(pageCurrent, pageSize);
        LambdaQueryWrapper<Role> qw = new LambdaQueryWrapper<>();
        qw.like(name!=null, Role::getName, name);
        Page<Role> rolePage = roleMapper.selectPage(pageInfo, qw);
        System.out.println("rolePage=" + rolePage);
        // 设置角色权限信息
        List<Role> roles = rolePage.getRecords();
        for (Role role: roles) {
            List<String> menuList = roleMapper.selectMenuByRoleId(role.getId());
            role.setMenuName(menuList);
        }
        return R.success().message("角色分页信息").data("rolePage", rolePage);
    }

    /**
     * 修改角色当前状态
     * @param id 要修改的用户id
     * @param status 状态码 0：正常 1：异常
     */
    @Override
    public void setStatus(Integer id, Integer status) {
        LambdaUpdateWrapper<Role> uw = new LambdaUpdateWrapper<>();
        uw.eq(Role::getId, id);
        uw.set(Role::getStatus, status);
        roleMapper.update(null, uw);
    }

    /**
     * 添加角色
     * @param role
     * @return
     */
    @Override
    public R addRole(Role role) {
        /*1、判断用户名是否重复，只要结果集的第一条数据，
        * 不然查出多个 roleMapper.selectOne 会报错*/
        LambdaQueryWrapper<Role> qw = new LambdaQueryWrapper<>();
        /*
        * SELECT * FROM t_role
        *   WHERE `name` = '测试员工5' OR 'role_key' = 'test'
        *   LIMIT 1
        * */
        qw.eq(Role::getName, role.getName());
        qw.or();
        qw.eq(Role::getRoleKey, role.getRoleKey());
        qw.last("limit 1");

        Role selectResult= roleMapper.selectOne(qw);
        if (!Objects.isNull(selectResult)){
            return R.error().message("添加角色失败，角色名称或关键字重复！");
        }

        //2、添加角色
        int insertResult = roleMapper.insert(role);
        if (insertResult==1){
            return R.success().message("角色添加成功");
        }
        return R.error().message("角色添加失败，系统错误，请联系管理员");
    }

    /**
     * 根据角色 id，删除角色 超级管理员角色无法删除
     * 并且删除角色权限信息
     * @param id 角色id
     * @return
     */
    @Override
    public R deleteRoleById(Integer id) {
        if (id==1){
            return R.error().message("超级管理员角色无法删除！");
        }
        int deleteResult = roleMapper.deleteById(id);
        //删除角色权限信息
        roleMapper.deleteMenuByRoleId(id);
        if (deleteResult==1){
            return R.success().message("角色删除成功");
        }
        return R.error().message("角色删除失败，系统错误，请联系管理员");
    }

    /**
     * 根据角色id，查询单个角色信息
     * @param id 角色id
     * @return
     */
    @Override
    public R selectOneById(Integer id) {
        LambdaQueryWrapper<Role> qw = new LambdaQueryWrapper<>();
        qw.eq(Role::getId, id);
        Role role = roleMapper.selectOne(qw);
        return R.success().message("根据id，查询单个角色数据").data("role", role);
    }

    /**
     * 修改角色信息
     * @param role
     * @return
     */
    @Override
    public R updateRole(Role role) {
        //1、判断角色名称和角色关键字是否重复
        LambdaQueryWrapper<Role> qw = new LambdaQueryWrapper<>();
        qw.eq(Role::getName, role.getName());
        qw.or();
        qw.eq(Role::getRoleKey, role.getRoleKey());
        qw.last("limit 1");
        Role selectResult = roleMapper.selectOne(qw);
        if (!Objects.isNull(selectResult)&&selectResult.getId()!=role.getId()){
            return R.error().message("添加员工失败，角色名称或关键字重复！");
        }
        //2、修改用户信息
        int updateResult = roleMapper.updateById(role);
        if (updateResult==1){
            return R.success().message("修改成功！");
        }
        return R.error().message("修改失败，请联系管理员！");
    }

    /**
     * 批量删除 超级管理员角色无法删除
     * 并且删除角色权限信息
     * @param ids 角色 id数组
     * @return
     */
    @Override
    public R deleteRoleBatch(List<Integer> ids) {
        //当数组只有一个id时，判断是不是超级管理员角色
        if (ids.size() == 1&&ids.get(0)==1){
            return R.error().message("批量删除失败，无法删除超级管理员角色");
        }
        //当数组只有一个id时，超级管理员角色跳过
        for (Integer id: ids) {
            if (id==1){
                continue;
            }
            int deleteResult = roleMapper.deleteById(id);
            //删除角色权限信息
            roleMapper.deleteMenuByRoleId(id);
            if (deleteResult!=1){
                return R.error().message("批量删除失败，系统错误，请联系管理员");
            }
        }
        return R.success().message("批量删除成功");
    }

    /**
     * 角色信息 -- 导出 Excel
     * @param response
     * @return
     */
    @Override
    public void outExcel(HttpServletResponse response) {
        try{
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            //1、 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("角色基本信息表", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            //2、查询数据库数据
            LambdaQueryWrapper<Role> qw = new LambdaQueryWrapper<>();
            List<Role> roles = roleMapper.selectList(qw);
            //查询角色的权限信息 EasyExcel 不支持 List 数据可能会报错，需要自定义 Converter 实现类
            for (Role role: roles) {
                List<String> menuList = roleMapper.selectMenuByRoleId(role.getId());
                role.setMenuName(menuList);
            }

            //3、设置要排除的字段
            HashSet<String> set = new HashSet<>();


            EasyExcel.write(response.getOutputStream(),Role.class)
                    .sheet("角色基本信息表")
                    .excludeColumnFiledNames(set)
                    // 自定义 Converter 接口 实现类
                    .registerConverter(new ListStringConverter())
                    .doWrite(roles);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 角色信息 -- 导入 Excel
     * @param file
     * @return
     */
    @Override
    public void inExcel(MultipartFile file) {
        try {
            EasyExcel.read(file.getInputStream(), Role.class, new AnalysisEventListener<Role>() {

                @Override
                public void doAfterAllAnalysed(AnalysisContext arg0) {
                    System.out.println("Excel全部读完被执行......");
                }

                @Override
                public void invoke(Role data, AnalysisContext arg1) {
                    System.out.println("解析一行: "+ data);
                    addRole(data);
                }
            }).sheet("角色基本信息表")
                    .registerConverter(new ListStringConverter())
                    .doRead();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 通过角色id，获取此角色的权限 id 列表
     * @param id
     * @return
     */
    @Override
    public R getMenuByRoleId(Integer id) {
        List<Integer> menuIds = roleMapper.selectMenuIdListByRoleId(id);
        return R.success().message("当前 id 角色所拥有的权限 id 列表").data("menuIds", menuIds);
    }


    /**
     * 为 角色添加权限
     * @param id 待添加的角色id
     * @param menuIds 添加的权限id数组
     * @return
     */
    @Override
    public R addMenuForRole(Integer id, Integer[] menuIds) {
        //1、添加前先删除 这个角色的所有 权限信息
        roleMapper.deleteMenuByRoleId(id);
        //2、添加
        for (Integer menuId: menuIds) {
            roleMapper.addMenuForRole(id, menuId);
        }
        return R.success().message("角色权限分配成功！");
    }


}
